package com.bilibili.juc.cf.base;

import com.google.common.util.concurrent.*;
import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

public class FutureAdapter {

    // 将 CompletableFuture 转为 ListenableFuture
    public static <T> ListenableFuture<T> toListenableFuture(CompletableFuture<T> completableFuture, Executor executor) {
        SettableFuture<T> settableFuture = SettableFuture.create();
        completableFuture.whenCompleteAsync((result, ex) -> {
            if (ex != null) {
                settableFuture.setException(ex);
            } else {
                settableFuture.set(result);
            }
        }, executor);
        return settableFuture;
    }

    // 将 ListenableFuture 转为 CompletableFuture
    public static <T> CompletableFuture<T> toCompletableFuture(ListenableFuture<T> listenableFuture, Executor executor) {
        CompletableFuture<T> completableFuture = new CompletableFuture<>();
        Futures.addCallback(listenableFuture, new FutureCallback<T>() {
            @Override
            public void onSuccess(T result) {
                completableFuture.complete(result);
            }

            @Override
            public void onFailure(Throwable t) {
                completableFuture.completeExceptionally(t);
            }
        }, executor);
        return completableFuture;
    }

    @Test
    public void toCompletableFutureTest() {
        ListeningExecutorService guavaExecutor = MoreExecutors.newDirectExecutorService();
        ListenableFuture<String> guavaFuture = guavaExecutor.submit(() -> "Hello from Guava");

        // 转换为 CompletableFuture
        CompletableFuture<String> javaFuture = toCompletableFuture(guavaFuture, MoreExecutors.directExecutor());

        // 使用 CompletableFuture 链式操作
        javaFuture.thenAccept(result -> System.out.println("CompletableFuture Result: " + result));
    }

    @Test
    public  void toListenableFutureTest() {
        CompletableFuture<String> javaFuture = CompletableFuture.supplyAsync(() -> "Hello from CompletableFuture");

        // 转换为 ListenableFuture
        ListenableFuture<String> guavaFuture = toListenableFuture(javaFuture, MoreExecutors.directExecutor());

        // 添加 Guava 回调
        Futures.addCallback(guavaFuture, new FutureCallback<String>() {
            @Override
            public void onSuccess(String result) {
                System.out.println("Guava Future Result: " + result);
            }

            @Override
            public void onFailure(Throwable t) {
                System.err.println("Guava Future Failed: " + t.getMessage());
            }
        }, MoreExecutors.directExecutor());

    }
}